package org.loong.crypto.service.software.provider.hmac;

import java.util.Objects;

import org.loong.crypto.common.exception.CryptoException;
import org.loong.crypto.common.exception.InvalidKeyException;
import org.loong.crypto.common.exception.InvalidKeyLengthException;
import org.loong.crypto.common.utils.ByteUtils;
import org.loong.crypto.core.algorithm.HmacAlgorithm;
import org.loong.crypto.service.core.provider.HmacSigner;
import org.loong.crypto.service.core.provider.impl.BaseHmacProvider;

import cn.hutool.crypto.digest.HMac;

/**
 * Generic HMAC singer.
 */
public class GenericHmacSinger extends BaseHmacProvider implements HmacSigner {

    public GenericHmacSinger(final byte[] secret) throws InvalidKeyException, InvalidKeyLengthException {
        super(secret);
    }

    @Override
    public byte[] sign(HmacAlgorithm algorithm, byte[] message) throws CryptoException {
        // secret size in bits
        int bitLength = ByteUtils.safeBitLength(getSecret().length);
        if (Objects.nonNull(algorithm.getKeyLength()) && bitLength < algorithm.getKeyLength()) {
            throw new InvalidKeyLengthException("The secret length must be at least " + algorithm.getKeyLength() + " bits.");
        }

        HMac hmac = new HMac(algorithm.getName(), getSecret());
        return hmac.digest(message);
    }
}
